import { CellProperty } from "../types";

export * from "./bitOperation";
export * from "./ioOperation";

export function handleRawData(rawData: string[]): number[] {
  if (rawData.length < 9) {
    throw new Error("invalid input, less than 9 lines");
  } else if (rawData.length > 9) {
    rawData = rawData.slice(0, 9);
  }
  let table: number[] = [];
  for (let i = 0; i < 9; i++) {
    if (rawData[i].length < 9) {
      throw new Error("invalid input, less than 9 characters");
    } else if (rawData[i].length > 9) {
      rawData[i] = rawData[i].slice(0, 9);
    }
    for (let j = 0; j < 9; j++) {
      let num = parseInt(rawData[i][j]);
      table.push(isNaN(num) || num < 0 || num > 9 ? 0 : num);
    }
  }
  return table;
}

/**
 *
 * @param idx 输入的单元格索引
 * @returns 该单元格所在的行、列、块的索引
 */
export function idx2RCB(idx: number): number[] {
  if (idx < 0 || idx > 80) {
    throw new Error(`error idx: ${idx}, a idx must between 0~80.`);
  }
  // 计算行和列
  const row = Math.floor(idx / 9);
  const col = idx % 9;
  return [row, col, Math.floor(row / 3) * 3 + Math.floor(col / 3)];
}

/**
 *
 * @param rcbIdx 输入的行或列或块的索引
 * @param property 索引属性
 * @return 该行或列或块的所有单元格索引
 */
export function RCB2Idx(rcbIdx: number, property: CellProperty): number[] {
  if (rcbIdx < 0 || rcbIdx > 8) {
    throw new Error(`error rcbIdx: ${rcbIdx}, a rcbIdx must between 0~8.`);
  }
  const ret = new Array<number>(9).fill(0);
  if (property === CellProperty.row) {
    return ret.map((_, idx) => rcbIdx * 9 + idx);
  } else if (property === CellProperty.col) {
    return ret.map((_, idx) => rcbIdx + idx * 9);
  } else {
    const rowOffset = Math.floor(rcbIdx / 3) * 3;
    const colOffset = (rcbIdx % 3) * 3;
    return ret.map(
      (_, idx) =>
        rowOffset * 9 + colOffset + Math.floor(idx / 3) * 9 + (idx % 3)
    );
  }
}
